<template>
  <div>
    <el-select
      v-model="selectedValue"
      filterable
      placeholder="请选择"
      @visible-change="handleVisibleChange"
      @filter-change="handleFilterChange"
      @blur="dropdownVisible = false"
      @focus="dropdownVisible = true"
      style="width: 300px"
      :teleported="false"
      :popper-class="'custom-dropdown'"
      :remote="true"
      :remote-method="remoteSearch"
    >
      <template #default>
        <RecycleScroller
          v-if="dropdownVisible"
          class="virtual-select-list"
          :items="filteredOptions"
          :item-size="40"
          key-field="id"
        >
          <template #default="{ item }">
            <el-option
              :label="item.label"
              :value="item.id"
              class="custom-option"
            >
              {{ item.label }}
            </el-option>
          </template>
        </RecycleScroller>
      </template>
    </el-select>

    <!-- 显示选中的 label -->
    <div style="margin-top: 20px;">
      选中项: {{ selectedLabel }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { RecycleScroller } from 'vue-virtual-scroller'

const selectedValue = ref('')
const dropdownVisible = ref(false)
const searchKeyword = ref('')

// 模拟 10 万条数据
const allOptions = ref(
  Array.from({ length: 100000 }, (_, i) => ({
    id: String(i),
    label: `选项 ${i + 1}`,
  }))
)

// 过滤选项
const filteredOptions = computed(() => {
  if (!searchKeyword.value) return allOptions.value
  return allOptions.value.filter(option =>
    option.label.includes(searchKeyword.value)
  )
})

// 选中 label，用于显示和打印
const selectedLabel = computed(() => {
  const found = allOptions.value.find(item => item.id === selectedValue.value)
  return found ? found.label : ''
})

// 监听选中变化，打印选中值和对应 label
watch(selectedValue, (val) => {
  const found = allOptions.value.find(item => item.id === val)
  console.log('选中值:', val)
  console.log('选中标签:', found ? found.label : '')
})

function handleVisibleChange(val: boolean) {
  dropdownVisible.value = val
}

function handleFilterChange(val: string) {
  searchKeyword.value = val
}

function remoteSearch(query: string) {
  searchKeyword.value = query
}
</script>

<style scoped>
.custom-dropdown {
  padding: 0;
}

.virtual-select-list {
  height: 100px;
  overflow-y: auto;
}

.custom-option {
  height: 40px;
  line-height: 40px;
}
</style>
